"""
@Author：WangYuXiang
@E-mile：Hill@3io.cc
@CreateTime：2021/4/12 17:41
@DependencyLibrary：无
@MainFunction：无
@FileDoc： 
    permission.py
    文件说明
@ChangeHistory:
    datetime action why
    example:
    2021/4/12 17:41 change 'Fix bug'
        
"""
from typing import List, Any

from common.auth.models import PermissionModel, GroupModel, RoleModel
from common.auth.serializers import EmpowerPermissionSerializer, PermissionModelSerializer, \
    PermissionHandlePostSerializer, PermissionHandleGetSerializer
from common.utils.authentication import GeneralTokenAuthenticate
from common.utils.site_views import AdminSiteView
from srf.exceptions import APIException
from srf.views import APIView
from srf import generics


def extract_code(objs: List[PermissionModel]) -> List[str]:
    """
    提取权限内的code

    :param objs: objs
    :return: 权限code列表
    :rtype: list
    """
    return [i.code for i in objs]


async def conduct_empower_permission(instance: Any):
    """
    处理权限，组合成前端需要的Json
    :param instance:
    :return:
    """
    permissions = {}

    role_permission_codes = extract_code(await instance.all_permissions())
    role_no_inherit_permission_codes = extract_code(await instance.all_permissions(is_inherit=False))

    all_permissions = await PermissionModel.all().group_by('classify_code')
    for permission in all_permissions:
        classify_code = permission.classify_code
        classify_name = permission.classify_name
        code = permission.code
        name = permission.name
        has = code in role_permission_codes
        disabled = code not in role_no_inherit_permission_codes and has

        if classify_code not in permissions:
            permissions[classify_code] = {
                'label': classify_name,
                'permissions': {}
            }
        permissions[classify_code]['permissions'][code] = {
            'label': name,
            'has': has,
            'disabled': disabled,
            'original': has and not disabled
        }
    return permissions


class PermissionViewSet(AdminSiteView):
    lookup_field = 'code'
    queryset = PermissionModel
    serializer_class = PermissionModelSerializer
    authentication_classes = (GeneralTokenAuthenticate,)
    search_fields = ('@code', '@name')


class EmpowerGroupPermission(generics.RetrieveUpdateAPIView):
    """对组进行授权操作"""
    queryset = GroupModel
    serializer_class = EmpowerPermissionSerializer
    authentication_classes = (GeneralTokenAuthenticate,)

    async def retrieve(self, request, *args, **kwargs):
        instance = await self.get_object()
        permission_json = await conduct_empower_permission(instance)
        return self.success_json_response(data=permission_json)

    async def update(self, request, *args, **kwargs):
        instance = await self.get_object()
        serializer = self.get_serializer(instance, data=request.data)
        await serializer.is_valid(raise_exception=True)
        await self.perform_update(serializer)
        permission_json = await conduct_empower_permission(instance)
        return self.success_json_response(msg='修改成功', data=permission_json)


class EmpowerRolePermission(EmpowerGroupPermission):
    """对组进行授权操作"""
    queryset = RoleModel
